package blue.http.internal.core.handler;

import blue.base.core.util.AssertUtil;
import blue.http.core.filter.HttpFilter;
import blue.http.core.message.HttpRequest;
import blue.http.core.message.HttpResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.List;

/**
 * @author Jin Zheng
 * @since 2020-01-05
 */
public class HttpHandlerChain implements HandlerChain<HttpRequest, HttpResponse> {
	private static Logger logger = LoggerFactory.getLogger(HttpHandlerChain.class);

	private Object handler;
	private List<HttpFilter> filterList = new ArrayList<>();
	private int filterIndex = -1;

	public HttpHandlerChain(Object handler) {
		this(handler, null);
	}

	public HttpHandlerChain(Object handler, List<HttpFilter> filterList) {
		AssertUtil.notNull(handler, "Handler");
		this.handler = handler;
		if (filterList != null && !filterList.isEmpty()) {
			this.filterList.addAll(filterList);
		}
	}

	@Override
	public boolean applyPreHandle(HttpRequest request, HttpResponse response) throws Exception {
		for (int i = 0; i < filterList.size(); i++) {
			this.filterIndex = i;
			HttpFilter filter = filterList.get(i);
			if (!filter.preHandle(request, response)) {
				return false;
			}
		}
		return true;
	}

	@Override
	public void applyPostHandle(HttpRequest request, HttpResponse response) throws Exception {
		for (int i = filterList.size() - 1; i >= 0; i--) {
			HttpFilter filter = filterList.get(i);
			filter.postHandle(request, response);
		}
	}

	@Override
	public void triggerAfterCompletion(HttpRequest request, HttpResponse response, Exception ex) {
		for (int i = filterIndex; i >= 0; i--) {
			HttpFilter filter = filterList.get(i);
			try {
				filter.afterCompletion(request, response, ex);
			}
			catch (Exception e) {
				logger.error("HttpFilter.afterCompletion throw exception,", e);
			}
		}
	}

	@Override
	public Object getHandler() {
		return handler;
	}

}
